//------------------------------------------------------------------------------
// X2TK Graphic Toolkit
// Copyright (C) 2006-2007 Janusz Kowalski
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//------------------------------------------------------------------------------

#include "x2tk_Button.h"
#include "x2tk.h"

#include "imgSDL.h"

#include "global.h"

#include <cassert>
#include <cstdio>

namespace x2tk {

// !! Image of the button should be rather vertical than,
// as it currently is, horizontal.

// Creates SDL surface containing a nice-looking graphic box drawn using
// the given template image (shape).
// shape - any SDL_Surface that meets the condition: width = 8*height.
// fill - any SDL surface used as the baskground texture.
// This function is quite slow. It shouldn't be called too often.
// SDL_Surface *makeNiceBox(SDL_Surface *shape, SDL_Surface *fill, int w, int h) {
//   assert(shape!=0); assert(fill!=0);
//   assert(shape->w==8*shape->h);
//   
//   SDL_Surface *surf;
//   surf=SDL_CreateRGBSurface(SDL_SWSURFACE,w,h,24,0x000000ff,0x0000ff00,0x00ff0000, 0);
//   
//   assert(surf!=0);
//   
//   // Fill background with the texture
//   SDL_Rect dstrect={0,0,0,0};
//   for(int y=0; y<h; y+=fill->h)
//     for(int x=0; x<w; x+=fill->w) {
//       dstrect.x=x; dstrect.y=y;
//       SDL_BlitSurface(fill, 0, surf, &dstrect);
//     }
//   
//   SDL_Rect cliprect;
// 
//   int length=shape->h;
//   SDL_Rect srcrect={0,0,length,length};
//   
//   if(h>2*length) {
//     cliprect.x=0; cliprect.y=length;
//     cliprect.w=w; cliprect.h=h-2*length;
//     SDL_SetClipRect(surf,&cliprect);
//     // Draw the left edge
//     srcrect.x=3*length; dstrect.x=0;
//     for(int y=0;y<surf->h;y+=length) {
//       dstrect.y=y;
//       SDL_BlitSurface(shape, &srcrect, surf, &dstrect);
//     }
//     
//     // Draw the right edge
//     srcrect.x=4*length; dstrect.x=surf->w-length;
//     for(int y=0; y<surf->h; y+=length) {
//       dstrect.y=y;
//       SDL_BlitSurface(shape, &srcrect, surf, &dstrect);
//     }
//   }
//   
//   if(w>2*length) {
//     cliprect.x=length; cliprect.y=0;
//     cliprect.w=w-2*length; cliprect.h=h;
//     SDL_SetClipRect(surf,&cliprect);
//     // Draw the top egde
//     srcrect.x=1*length; dstrect.y=0;
//     for(int x=0; x<surf->w; x+=length) {
//       dstrect.x=x;
//       SDL_BlitSurface(shape, &srcrect, surf, &dstrect);
//     }
//     
//     // Draw the bottom edge
//     srcrect.x=6*length; dstrect.y=surf->h-length;
//     for(int x=0; x<surf->w; x+=length) {
//       dstrect.x=x;
//       SDL_BlitSurface(shape, &srcrect, surf, &dstrect);
//     }
//   }
//   
//   SDL_SetClipRect(surf,0);
//   
//   int srcf[4]={0,2,5,7};
//   int dstx[4]={0,w-length,0,w-length};
//   int dsty[4]={0,0,h-length,h-length};
//   
//   for(int i=0; i<4; i++) {
//     srcrect.x=srcf[i]*length; dstrect.x=dstx[i]; dstrect.y=dsty[i];
//     SDL_BlitSurface(shape, &srcrect, surf, &dstrect);
//   }
//   
//   SDL_SetColorKey(surf, SDL_SRCCOLORKEY, SDL_MapRGB(surf->format, 0xff, 0x00, 0xff));
//   
//   SDL_Surface *finalSurf;
//   
//   finalSurf=SDL_DisplayFormat(surf);
//   SDL_FreeSurface(surf);
//   
//   return finalSurf;
// }

Button::Button(int x, int y, int w, int h, const char *label) : Widget(x,y,w,h) {
  font_ = Font(X2D_PATH_FONT "HiTechFont_Black.png");
  image=0;
  imagePressed=0;
  imageFocus=0;
  isPressed=false;
  isHovered=false;
  labelText=label;
  texNormal=Image(X2D_PATH_DATA "circles/texC.png");
  texPressed=Image(X2D_PATH_DATA "crcles/texD.png");
}

Button::Button(const char *label, int defaultActionId) : Widget(10,10,128,128) {
  font_ = Font(X2D_PATH_DATA "HiTechFont_Black.png");
  image=0;
  imagePressed=0;
  imageFocus=0;
  this->defaultActionId=defaultActionId;
  isPressed=false;
  labelText=label;
  if(label!=0) {
    int sl;
    for(sl=0; label[sl]!=0; sl++);
    resize(sl*16+32, 32);
  } else resize(128, 32);
  image=0;
  texNormal=Image(X2D_PATH_DATA "circles/texC.png");
  texPressed=Image(X2D_PATH_DATA "circles/texD.png");
}

void Button::setAction(int action) {
  defaultActionId=action;
}

Button::~Button() {
  if(image!=0) SDL_FreeSurface(image);
  if(imagePressed!=0) SDL_FreeSurface(image);
}

void Button::resize(int w, int h) {
  Widget::resize(w,h);
  changed=true;
}

void Button::draw(GraphicContext &g) {
  Uint32 fgColor = x2tk::getColor(FRAME_NORMAL);
  
  if(isPressed && isHovered) g.setColor(x2tk::getColor(AREA_NORMAL));
  else g.setColor(x2tk::getColor(AREA_CLICKABLE));
  g.filledRectangle(0,0,getW(),getH());
  
  g.hLine(1,1,getW());

  if(hasFocus()) g.setColor(x2tk::getColor(FRAME_ACTIVE));
  else g.setColor(x2tk::getColor(FRAME_NORMAL));
  g.rectangle(0,0,getW(),getH());
  
  //Sint16 vx[6]={0,4,getW()-1,getW()-1,   getW()-1-4, 0};
  //Sint16 vy[6]={4,0,0,     getH()-1-4, getH()-1, getH()-1};
  
  //SDL_Surface *tex;
  //if(isPressed) tex=texPressed.getSurf();
  //else tex=texNormal.getSurf();
  
  //g.texdPolygon(vx,vy,6,tex,0,0);
  
  //g.RGBAPolygon(vx,vy,6,0,0,0,255);
  
  // Draw focus.
//   if(getFocus()) {
//     int s = 2;
//     Sint16 vx[6]={s,4,getW()-1-s,getW()-1-s,   getW()-1-4, s};
//     Sint16 vy[6]={4,s,s,         getH()-1-4, getH()-1-s, getH()-1-s};
//     g.setColor(0xFF,0x66,0x00,0xFF);
//     g.filledPolygon(vx,vy,6);
//   }

  // Draw some text
  int labelX=(getW()-font_.getW(labelText))/2;
  int labelY=(getH()-16)/2;
  
  font_.drawText(g, labelX, labelY, labelText);
}

bool Button::mouseDown(int type) {
  if(Widget::mouseDown(type)) {
    if(type==1) isPressed=true;
    return true;
  }
  return false;
}

void Button::mouseUp(int type) {
  // Simple code.
  if((type==1) && isPressed) {
    if(isHovered && defaultActionId!=0) callLater(this, 0);
    isPressed=false;
  }
}

void Button::mouseMove(int x, int y) {
  if(x<0 || !(x<getW())) {isHovered=false; return;}
  if(y<0 || !(y<getH())) {isHovered=false; return;}
  isHovered=true;
}

void Button::event_key(const SDL_KeyboardEvent& key) {
  Widget::event_key(key);
  
  if(key.keysym.sym==SDLK_RETURN) {
    if(key.type==SDL_KEYDOWN) callLater(this,0);
  }
}

void Button::timed(int id) {
  if(defaultActionId!=0) action(defaultActionId, this);
}

} // namespace x2tk
